// Filename:    AutoJob.cpp
// Author:      John Van Drasek
// Date:		3/11/2011
// Description:


// Includes
// Windows
#include <stdio.h>
// RUP
#include "RUP.h"
// Threading
#include "pthread.h"
// AutoJob
#include "Login.h"
#include "AutoJob_Globals.h"

static const int MAX_COMMANDLINE_REMOTEIP_SIZE = 16; // 15 for ip and 1 for null terminiator
static const int MAX_CMD_LINE_PARAMETERS = 2;

bool ExecuteCommandsOnRemoteSystem(char* in_remoteIP, char* in_commands)
{
	// Variable declarations
	int sock, rc, fromlen;
	bool result;
	struct pkt* myPkt;
	struct pkt inPkt;
	struct sockaddr_in client;
	struct sockaddr_in from;
	struct hostent *h;

	// Variable assignments
	result = false;
	fromlen = sizeof(struct sockaddr_in);

	// **Important for Winsock**
	// RUP calls WSAStartup() in the rup_open(), which is required
	// prior to any calls including gethostbyname() which notice is
	// right after this call.
	// Create socket
	sock = rup_open();

	printf("Contacting remote system: %s\n", in_remoteIP);
	// Assign values to the client sockaddr_in struct
	//   family - INET is tcp/ip/ethernet
	//   addr - IP address of server
	//   port - Port number of server
	h = gethostbyname(in_remoteIP);
	if ( h == 0 )
	{
		printf("ERROR(ExecuteCommandsOnRemoteSystem): cannot find host %s\n",in_remoteIP);
		//printf("Press any key to exit...\n");
		//getchar();
		exit(2);
	}

	memcpy(&client.sin_addr, h->h_addr, h->h_length);
	client.sin_family = AF_INET;

	// convert host short to network byteorder short
	client.sin_port = htons(SERVERLOGINPORT);

	// Create a pkt
	//myPkt = createPkt(1,"login",&client,inUsername,inPassword,"",0);
	//myPkt = createPkt(1,"login",&client,"jv","jv","",0);
	myPkt = createPkt(1,"execute",&client,"jv","jv",in_commands,0);

	// Performing the checksum and assigning it to the pkt
	myPkt->_checksum = performChecksum(myPkt);
	
	printf("Sending RPC request...\n", in_remoteIP);
	// Write login pkt to server
	if(rup_write(sock,myPkt,sizeof(struct pkt),&client) < 0)
	{
		if(errno == ENOBUFS)
		{
			printf("ERROR(ExecuteCommandsOnRemoteSystem) Client Error: sending datagram.  errno %d\n", errno);
		}
		//printf("Press any key to exit...\n");
		//getchar();
		exit(1);
	}

	// Read result pkt from server
	if ((rc=rup_read(sock, &inPkt, sizeof(struct pkt), &from)) < 0 )
	{
		printf("ERROR(ExecuteCommandsOnRemoteSystem): chat server error: errno %d\n",errno);
		printf("reading datagram\n");
		//printf("Press any key to exit...\n");
		//getchar();
		exit(1);
	}

	// check to see if return message is success
	if(strcmp(inPkt._msgbuf,"success") == 0)
	{
		// Set return value to true
		result = true;
		strncpy_s(gServerAddress, ADDRESSSIZE, in_remoteIP, strlen(in_remoteIP));
		//    strncpy_s(gServerAddress, strlen(inServerAddress), inServerAddress, strlen(inServerAddress));
		strncpy_s(gUsername, NAMESIZE, "", 0);
		//    strncpy_s(gUsername, strlen(inUsername), inUsername, strlen(inUsername));

		// Check to see if return message is failure
		printf("Commands are being executed on remote system.\n");
		printf("Please wait....\n");
	}
	else if(strcmp(inPkt._msgbuf,"failure") == 0)
	{
		// Set return value to false
		result = false;
		printf("ERROR(ExecuteCommandsOnRemoteSystem): Remote IP(%s) returned error.\n", in_remoteIP);
		// Return message is not success or failure
	}
	else
	{
		result = false;
		printf("ERROR(ExecuteCommandsOnRemoteSystem): Remote IP(%s) returned error.\n", in_remoteIP);
	}
	rup_close(sock);
	delete myPkt;

	//free(in_remoteIP);
	//free(in_commands);

	return result;
}


int main(int argc, char* argv[])
{
	int cmdLineParamLen = 0;
	char* remoteIP = NULL;
	bool result = false;
	char* commands = NULL;

	// Command line argument checks
	if(argc != (MAX_CMD_LINE_PARAMETERS + 1))
	{
		// Check to see if we have exactly one command line parameter.
		// The user must provide at least one command line parameter to be used as the remote ip address
		printf("ERROR(AutoJob): Missing command line parameter!\n");
		printf("arg 1: remote IP address\n");
		printf("arg 2: commands to execute string is larger than %d\n", BUFSIZE);
		return 0;
	}
	else
	{
		// Remote IP address
		// MAX_COMMANDLINE_PARAMETER_SIZE-1 is the max size for an IP address.  MAX_COMMANDLINE_PARAMETER_SIZE is
		// defined to be one more than the max size to include space for the null terminator
		result = strnlen(argv[1], MAX_COMMANDLINE_REMOTEIP_SIZE) > MAX_COMMANDLINE_REMOTEIP_SIZE-1;
		if(true == result)
		{
			// Check to see if command line argument is too long
			printf("ERROR(AutoJob): Command line arg too long! Param #1: remote IP address is too long!\n");
			return 0;
		}
		else
		{
			// Store our ip address from the command line
			cmdLineParamLen = strnlen(argv[1],MAX_COMMANDLINE_REMOTEIP_SIZE) + 1;  // Add 1 for null terminator
			remoteIP = (char*)malloc(cmdLineParamLen);
			memset(remoteIP, 0, cmdLineParamLen);
			strncpy(remoteIP, argv[1], cmdLineParamLen);
			strncpy(gServerAddress, remoteIP, strlen(remoteIP));
			remoteIP[cmdLineParamLen-1] = '\0'; // Set null terminator to last position
		}


		// Commands to execute
		// FIXME: BUFSIZE is 1024 and we are only allowing a command size of 1023 with this code
		result = strnlen(argv[2], BUFSIZE) > BUFSIZE-1;
		if(true == result)
		{
			// Check to see if command line argument is too long
			printf("ERROR(AutoJob): Command line arg too long! Param #2: commands to execute is too long!\n");
			return 0;
		}
		else
		{
			// Store our ip address from the command line
			cmdLineParamLen = strnlen(argv[2],BUFSIZE) + 1;  // Add 1 for null terminator
			commands = (char*)malloc(cmdLineParamLen);
			memset(commands, 0, cmdLineParamLen);
			strncpy(commands, argv[2], cmdLineParamLen);
			commands[cmdLineParamLen-1] = '\0'; // Set null terminator to last position
		}


	}

	// Run the smoke test on the remote system
	result = ExecuteCommandsOnRemoteSystem(remoteIP,commands);

	// Log out of server
	result = LogoutOfServer();
	if(result)
	{
		printf("Successfully logged out of server.\n");
	}
	else
	{
		printf("FAILED to log out of server.\n");
	}

	// Release resources
	free(remoteIP);
	free(commands);

	return 0;
}